package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.heima.apis.wemedia.IWemediaClient;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.HotArticleService;
import com.heima.common.constant.ArticleConstants;
import com.heima.common.constant.WmNewsMessageConstants;
import com.heima.common.redis.CacheService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.vos.HotArticleVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
public class HotArticleServiceImpl implements HotArticleService {
    @Autowired
    private ApArticleMapper apArticleMapper;
    @Autowired
    private IWemediaClient iWemediaClient;
    @Autowired
    private CacheService cacheService;

    /**
     * 计算热点文章
     */
    @Override
    public void computeHotArticle() {
        //获取前五天的文章数据
        log.info("【计算热点文章】--- begin");
        Date date = DateTime.now().minusDays(5).toDate();
        List<ApArticle> articleList = apArticleMapper.findArticleListByLast5days(date);
        log.info("前五天文章:{}",articleList);
        //2.计算文章分值
        log.info("计算分值");
        List<HotArticleVo> hotArticleVoList = computeHotArticleScore(articleList);
        log.info("计算分值结果:{}",hotArticleVoList);
        //3.为每个频道缓存30条分值较高的文章
        cacheTagToRedis(hotArticleVoList);
        log.info("【计算热点文章】--- end");

    }

    /**
     * 为每个频道缓存30条热点数据
     * @param hotArticleVoList
     */
    private void cacheTagToRedis(List<HotArticleVo> hotArticleVoList) {
        System.out.println(hotArticleVoList);
        if(hotArticleVoList != null && !hotArticleVoList.isEmpty()){
            ResponseResult response = iWemediaClient.getChannels();
            if(response.getCode().equals(200)){
                String channelString = JSON.toJSONString(response.getData());
                List<WmChannel> wmChannelList = JSON.parseArray(channelString, WmChannel.class);
                //检索出每个频道的文章
                if(wmChannelList != null && !wmChannelList.isEmpty()){
                    for (WmChannel wmChannel : wmChannelList) {
                        //获取对应频道的文章
                        try{
                            //List<HotArticleVo> hotArticleVos = hotArticleVoList.stream().filter(x -> x.getChannelId().equals(wmChannel.getId())).collect(Collectors.toList());
                            List<HotArticleVo> hotArticleVos = hotArticleVoList.stream()
                                    .filter(x -> {
                                        log.debug("比较 channelId: 文章={}, 频道={}", x.getChannelId(), wmChannel.getId());
                                        return Objects.equals(x.getChannelId(), wmChannel.getId());
                                    })
                                    .collect(Collectors.toList());
                            //按照评分降序排序
                            extracted(hotArticleVos, ArticleConstants.HOT_ARTICLE_FIRST_PAGE + wmChannel.getId());
                        }catch (Exception e){
                            log.error("【计算热点文章】--- 获取对应频道的文章失败");
                        }
                    }
                }

            }

            //设置推荐数据
            try{
                extracted(hotArticleVoList, ArticleConstants.HOT_ARTICLE_FIRST_PAGE + ArticleConstants.DEFAULT_TAG);
            }catch (Exception e){
                log.error("设置推荐数据失败");
            }

        }

    }

    /**
     * 排序并缓存数据
     * @param hotArticleVos
     * @param key
     */
    private void extracted(List<HotArticleVo> hotArticleVos, String key) {
        hotArticleVos.stream().sorted((x, y) -> {
            return y.getScore() - x.getScore();
        });
        //取前30条数据
        if (hotArticleVos.size() > 30) {
            hotArticleVos.subList(0, 30);
        }
        //存入redis
        cacheService.set(key, JSONArray.toJSONString(hotArticleVos));
    }

    /**
     * 计算分值功能
     * @param articleList
     * @return
     */
    private List<HotArticleVo> computeHotArticleScore(List<ApArticle> articleList) {
        List<HotArticleVo> hotArticleVos = new ArrayList<>();
        if(articleList != null && !articleList.isEmpty()){
            for (ApArticle apArticle : articleList) {
                Integer score = computeScore(apArticle);
                HotArticleVo hotArticleVo = new HotArticleVo();
                BeanUtils.copyProperties(apArticle,hotArticleVo);
                hotArticleVo.setScore(score);
                hotArticleVos.add(hotArticleVo);
            }
        }
        return hotArticleVos;
    }

    /**
     * 计算分值功能具体实现
     * @param apArticle
     * @return
     */
    private int computeScore(ApArticle apArticle) {
        Integer scere = 0;
        if(apArticle.getLikes() != null){
            scere += apArticle.getLikes() * ArticleConstants.HOT_ARTICLE_LIKE_WEIGHT;
        }
        if(apArticle.getViews() != null){
            scere += apArticle.getViews();
        }
        if(apArticle.getComment() != null){
            scere += apArticle.getComment() * ArticleConstants.HOT_ARTICLE_COMMENT_WEIGHT;
        }
        if(apArticle.getCollection() != null){
            scere += apArticle.getCollection() * ArticleConstants.HOT_ARTICLE_COLLECTION_WEIGHT;
        }

        return scere;
    }


}
